﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Configuration;
using System.Media;
using System.Runtime.InteropServices;
using motion.Properties;

namespace motion.Alarm
{
	/// <summary>
	/// Description of AlarmManager.
	/// </summary>
	public class AlarmManager
	{
		#region Constants

		private const string TEMP_PICTURES_DIRECTORY_NAME_FORMAT = "screenshots_{0}";
		private const string SOURCE_PICTURES_DIRECTORY_NAME_FORMAT = @"images\{0}-{1}-{2}\";
		private const string DATETIME_FORMAT = "dd-MM-yyyy hh-mm-ss";
		private const string DIR_FORMAT = "{0}\\{1}";
		
		#endregion
		
		private SoundPlayer _player = new SoundPlayer();
		
		private static AlarmManager _instance = new AlarmManager();
		
		private AlarmManager() {}
		
		public static AlarmManager Instance
		{
			get
			{
				return _instance;
			}
		}
		
		public void SendEmailNotification()
		{
			MailMessage mailMessage = new MailMessage();
			mailMessage.To.Add(Settings.Default.EmailTo);

			MailAddress mailAddress = new MailAddress(Settings.Default.EmailFrom);
			mailMessage.From = mailAddress;

			mailMessage.Subject = Settings.Default.EmailSubject;
			mailMessage.Body = Settings.Default.EmailBody;

			SmtpClient smtpClient = new SmtpClient(Settings.Default.EmailSmtpServer);
			NetworkCredential credentials = new NetworkCredential(Settings.Default.EmailFrom, Settings.Default.EmailPassword);
			smtpClient.Credentials = credentials;

			smtpClient.Send(mailMessage);
		}

		public void BeginPicturesSending()
		{
			DateTime stopSendingTime = DateTime.Now;
			
			while(stopSendingTime + Settings.Default.PicturesSendingInterval > DateTime.Now)
			{
				SendFilesToFtp(GetListOfPicturesAndMoveThemInTempDirectory());
			}
		}
		
		private List<string> GetListOfPicturesAndMoveThemInTempDirectory()
		{
			List<string> listOfPictures = new List<string>();
			
			string picturesTempDirectory = string.Format(TEMP_PICTURES_DIRECTORY_NAME_FORMAT, DateTime.Now.ToString(DATETIME_FORMAT));
			
			foreach(string fileName in Directory.GetFiles(string.Format(SOURCE_PICTURES_DIRECTORY_NAME_FORMAT, DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day)))
			{
				FileInfo file = new FileInfo(fileName);
				if(DateTime.Now - file.CreationTime < Settings.Default.PicturesSendingTimeOut)
				{
					Directory.CreateDirectory(picturesTempDirectory);
					file.MoveTo(string.Format(DIR_FORMAT, picturesTempDirectory, file.Name));
					listOfPictures.Add(string.Format(DIR_FORMAT, picturesTempDirectory, file.Name));
				}
				else
				{
					file.Delete();
				}
			}
			
			return listOfPictures;
		}
		
		private void SendFilesToFtp(List<string> filePaths)
		{
			foreach(string filePath in filePaths)
			{
				Uri uri = new Uri(Settings.Default.FtpServer + Path.GetFileName(filePath));
				
				// Get the object used to communicate with the server.
				FtpWebRequest request = (FtpWebRequest) FtpWebRequest.Create(uri);
				
				request.Method = WebRequestMethods.Ftp.UploadFile;

				// This example assumes the FTP site uses anonymous logon.
				request.Credentials = new NetworkCredential(Settings.Default.FtpLogin, Settings.Default.FtpPassword);
				
				using(Stream ftpStream = request.GetRequestStream())
				{
					using (FileStream fileStream = File.OpenRead(filePath))
					{
						int length = 1024;
						byte[] buffer = new byte[length];
						int bytesRead;

						do
						{
							bytesRead = fileStream.Read(buffer, 0, length);
							ftpStream.Write(buffer, 0, bytesRead);
						}
						while (bytesRead != 0);
					}
				}
			}
		}

		[DllImport("winmm.dll")]
		public static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume);

		[DllImport("winmm.dll")]
		public static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume);
		
		public void PlayAlarmSound()
		{
			waveOutSetVolume(IntPtr.Zero, uint.MaxValue);
			
			string soundPath = Settings.Default.AlarmSoundPath;			
			_player.SoundLocation = soundPath;
			_player.Play();
		}
		
		public void StopPlayingAlarm()
		{
			_player.Stop();
		}
	}
}
